home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / gui4cli / ext / gcsound / src / iff.h < prev    next >
C/C++ Source or Header  |  1999-05-14  |  6KB  |  224 lines

  1.  
  2. // IFF 8SVX file handling routines - no stereo yet..
  3.  
  4. // ===============================================================
  5. // LoadSample() - return new handle
  6. // - Allocate handle, open file & fill in handle structure
  7. // - Read in the sample (or part of it if too long) into buffers
  8. // ===============================================================
  9. struct myhandle *loadsample (char *filename, struct base *bs)
  10. {
  11.   struct myhandle *h = NULL;
  12.   LONG   hd;
  13.   BOOL   okflag = 0;
  14.   struct DosLibrary *DOSBase;
  15.   struct ExecBase *SysBase;
  16.   DOSBase=bs->dosbase; SysBase=bs->sysbase;
  17.  
  18.   if (!(h = (struct myhandle *)AllocVec(sizeof(struct myhandle), CLEANMEM)))
  19.   {   PutStr ("No memory!\n");
  20.       return (NULL);
  21.   }
  22.   strcpy (h->path, filename);
  23.   h->bs = bs;
  24.  
  25.   // open file
  26.   if (!(h->fp = Open (filename, MODE_OLDFILE)))
  27.   {   PrintFault(IoErr(), NULL);
  28.       goto abort;
  29.   }
  30.  
  31.   // check file & get "FORM" length
  32.   FRead (h->fp, &hd, 4, 1);
  33.   if (hd != ID_FORM)
  34.   {   PutStr ("Not and IFF file!\n");
  35.       goto abort;
  36.   }
  37.   Seek (h->fp, 4, OFFSET_CURRENT);  // skip length
  38.  
  39.   // check if it's an 8SVX
  40.   FRead (h->fp, &hd, 4, 1);
  41.   if (hd != ID_8SVX)
  42.   {   PutStr ("Not and 8SVX file!\n");
  43.       goto abort;
  44.   }
  45.  
  46.   // read header structure VHDR
  47.   if ((getchunk (ID_VHDR, h->fp, DOSBase, SysBase)) <= 0)
  48.       goto abort;
  49.   FRead (h->fp, &h->vh, sizeof(struct VoiceHeader), 1);
  50.   
  51.   // goto data
  52.   if ((h->bodylength = getchunk (ID_BODY, h->fp, DOSBase, SysBase)) <= 0)
  53.       goto abort;
  54.  
  55.   // store start of data position
  56.   h->bodystart = Seek (h->fp, 0, OFFSET_CURRENT);
  57.   
  58.   // ---------- read in data..
  59.  
  60.   // if it's a short sample, get it & close the file
  61.   if (h->bodylength <= BUFFER_SIZE)
  62.   {
  63.       h->buffsize = h->bodylength;
  64.       h->buff1 = (UBYTE *)AllocVec(h->buffsize + 6, MEMF_CHIP | MEMF_CLEAR);
  65.       if (!(h->buff1))
  66.       {   PutStr ("No memory!\n");
  67.           goto abort;
  68.       }
  69.       if ((Read (h->fp, h->buff1, h->buffsize)) != h->buffsize)
  70.       {   PutStr ("Read error!\n");
  71.           goto abort;
  72.       }
  73.       Close (h->fp); h->fp = NULL;
  74.   }
  75.   else  // long sample - use double buffering
  76.   {
  77.       h->buffsize = BUFFER_SIZE / 2;
  78.       h->buff1 = (UBYTE *)AllocVec(h->buffsize + 6, MEMF_CHIP | MEMF_CLEAR);
  79.       h->buff2 = (UBYTE *)AllocVec(h->buffsize + 6, MEMF_CHIP | MEMF_CLEAR);
  80.       if (!(h->buff1) || !(h->buff2))
  81.       {   PutStr ("No memory!\n");
  82.           goto abort;
  83.       }
  84.       if ((Read (h->fp, h->buff1, h->buffsize)) == h->buffsize)
  85.       {   if ((Read (h->fp, h->buff2, h->buffsize)) == h->buffsize)
  86.               okflag = 1;
  87.       }
  88.       if (!okflag) goto abort;
  89.       // do not close file
  90.   }
  91.  
  92.   // structure filled ok..
  93.   h->next = NULL;
  94.   return (h);
  95.  
  96.   abort:
  97.   if (h) freehandle (h);
  98.   Printf ("Error parsing file %s\n", filename);
  99.   return (NULL);
  100. }
  101.  
  102.  
  103. // ===============================================================
  104. //  getchunk()
  105. //  look for named chunk, return it's length or -1
  106. //  file ptr is advanced to after the size - i.e. start of data
  107. // ===============================================================
  108.  
  109. LONG getchunk (LONG head, BPTR fp, 
  110.                struct DosLibrary *DOSBase, struct ExecBase *SysBase)
  111. {
  112.   LONG hd;
  113.   BOOL flag = FALSE;
  114.   LONG skip, length = -1;     // default: return -1
  115.  
  116.   // read header:
  117.   while (!flag && (FRead (fp, &hd, 4, 1) == 1))
  118.   {
  119.       // Have we found the right chunk?
  120.       if (hd == head)
  121.       {    // yes..
  122.            if ((FRead (fp, &length, 4, 1)) == 1)
  123.                 return (length);
  124.            return (-1L);
  125.       }
  126.       // otherwise move forward..
  127.       if ((FRead (fp, &skip, 4, 1)) == 1)
  128.       {   
  129.          Seek (fp, skip, OFFSET_CURRENT);
  130.       }
  131.       else ++flag;
  132.   }
  133.   return (-1L);
  134. }
  135.  
  136. // ===============================================================
  137. //    initialise loaded sample - set speed etc
  138. // ===============================================================
  139. void initsample (struct myhandle *h, char *alias, struct base *bs)
  140. {
  141.    struct myhandle *hh;
  142.  
  143.    if (!h) return;
  144.    h->speed  = bs->clock / h->vh.vh_SamplesPerSec;
  145.    h->volume = h->vh.vh_Volume / 1024;
  146.    h->times  = 1;
  147.    stccpy (h->alias, alias, 35);
  148.  
  149. // Printf ("=================\n", NULL);
  150. // Printf ("OneShot=%ld - Repeat=%ld\n", (LONG)h->vh.vh_OneShotHiSamples, (LONG)h->vh.vh_RepeatHiSamples);
  151. // Printf ("Volume=%ld - Speed=%ld\n", h->volume, h->speed);
  152.  
  153.    // link handle
  154.    if (!bs->toph) bs->toph = h;
  155.    else 
  156.    {  for (hh=bs->toph; hh->next; hh = hh->next);
  157.       hh->next = h;
  158.    }
  159. }
  160.  
  161. // ===============================================================
  162. //    reload sample
  163. // ===============================================================
  164. BOOL reload (struct myhandle *h)
  165. {
  166.    struct DosLibrary *DOSBase;
  167.    struct ExecBase *SysBase;
  168.    DOSBase=h->bs->dosbase; SysBase=h->bs->sysbase;
  169.    if (!h || !h->fp) return (0);
  170.  
  171.    Seek (h->fp, h->bodystart, OFFSET_BEGINNING);
  172.    if ((Read (h->fp, h->buff1, h->buffsize)) == h->buffsize)
  173.    {   if ((Read (h->fp, h->buff2, h->buffsize)) == h->buffsize)
  174.           return (1);
  175.    }
  176.    PutStr ("Error reading file!\n");
  177.    return (0);
  178. }
  179.  
  180. // ===============================================================
  181. //  freehandle()
  182. //  free handle , close file etc..
  183. // ===============================================================
  184.  
  185. void freehandle (struct myhandle *h)
  186. {
  187.    struct DosLibrary *DOSBase;
  188.    struct ExecBase *SysBase;
  189.    DOSBase=h->bs->dosbase; SysBase=h->bs->sysbase;
  190.  
  191.    if (h)
  192.    {   if (h->buff1) FreeVec (h->buff1);
  193.        if (h->buff2) FreeVec (h->buff2);
  194.        if (h->fp) Close (h->fp);
  195.        FreeVec (h);
  196.    }
  197. }
  198.  
  199. // ===============================================================
  200. //  remlink()
  201. //  unlink sample, ready to free it..
  202. // ===============================================================
  203.  
  204. void remlink (struct myhandle *h)
  205. {
  206.    struct base *bs;
  207.    struct myhandle *hh;
  208.  
  209.    if (!h) return;
  210.    bs = h->bs;
  211.    
  212.    if (h == bs->toph)
  213.        bs->toph = bs->toph->next;
  214.    else
  215.    {   hh = bs->toph;
  216.        while (hh && (hh->next != h)) hh = hh->next;
  217.        if (hh) hh->next = h->next;
  218.    }
  219.    h->next = NULL;
  220. }
  221.  
  222.  
  223.  
  224.